# -*- coding:utf8 -*-
"""
关闭资源管理器的zip预览功能, 减少CPU占用
"""
import winreg as reg
import os
import ctypes

REG_PATH_ZIP = r"SystemFileAssociations\.zip"
REG_PATH_CLSID = r"SystemFileAssociations\.zip\CLSID"
REG_PATH_CLSID_BAK = r"SystemFileAssociations\.zip\CLSID_BAK"
E88DCCE0 = "{E88DCCE0-B7B3-11d1-A9F0-00AA0060FA31}"


def clsid_is_e88dcce0():
    """
    判断 计算机\\HKEY_CLASSES_ROOT\\SystemFileAssociations\\.zip\\CLSID 注册表项的值
    是否为{E88DCCE0-B7B3-11d1-A9F0-00AA0060FA31}
    """
    return get_clsid_value() == E88DCCE0


def clsid_bak_is_e88dcce0():
    """
    判断 计算机\\HKEY_CLASSES_ROOT\\SystemFileAssociations\\.zip\\CLSID_BAK 注册表项的值
    是否为{E88DCCE0-B7B3-11d1-A9F0-00AA0060FA31}
    """
    return get_clsid_bak_value() == E88DCCE0


def get_clsid_value():
    """
    判断注册表项HKEY_CLASSES_ROOT\\SystemFileAssociations\\.zip\\CLSID是否存在。
    输出一些相关信息
    """
    print("")
    try:
        k = reg.OpenKey(reg.HKEY_CLASSES_ROOT, REG_PATH_CLSID, 0, reg.KEY_ALL_ACCESS)
    except FileNotFoundError as err:
        print(r"该注册表项不存在：计算机\HKEY_CLASSES_ROOT\SystemFileAssociations\.zip\CLSID", err)
        print("")
        return "不存在"
    except PermissionError as err:
        print("请以管理员身份运行本程序。", err)
        return "权限低"

    value = reg.QueryValue(k, "")
    info = reg.QueryInfoKey(k)
    k.Close()

    print("CLSID注册表项存在")
    print("默认值: " + value)
    print("信息：", info)

    if info[0] == 0:
        print("CLSID没有子项")
    else:
        print("CLSID有子项")
        return "有子项"

    if info[1] == 1:
        print("CLSID只有一个默认值")
    else:
        print("CLSID有多个值")
        return "多个值"

    return value


def get_clsid_bak_value():
    """
    判断注册表项HKEY_CLASSES_ROOT\\SystemFileAssociations\\.zip\\CLSID_BAK是否存在。
    输出一些相关信息
    """
    print("")
    try:
        k = reg.OpenKey(
            reg.HKEY_CLASSES_ROOT, REG_PATH_CLSID_BAK, 0, reg.KEY_ALL_ACCESS
        )
    except FileNotFoundError as err:
        print(
            r"该注册表项不存在：计算机\HKEY_CLASSES_ROOT\SystemFileAssociations\.zip\CLSID_BAK", err
        )
        print("")
        return "不存在"
    except PermissionError as err:
        print("请以管理员身份运行本程序。", err)
        return "权限低"

    value = reg.QueryValue(k, "")
    info = reg.QueryInfoKey(k)
    k.Close()

    print("CLSID_BAK该注册表项存在")
    print("默认值: " + value)
    print("信息：", info)

    if info[0] == 0:
        print("CLSID_BAK没有子项")
    else:
        print("CLSID_BAK有子项")
        return "有子项"

    if info[1] == 1:
        print("CLSID_BAK只有一个默认值")
    else:
        print("CLSID_BAK有多个值")
        return "多个值"

    return value


def backup_clsid():
    """
    将clsid重命名为clsid_bak。
    原理是删除重新创建。
    """
    if not clsid_is_e88dcce0():
        return

    k = reg.OpenKey(
        reg.HKEY_CLASSES_ROOT,
        REG_PATH_ZIP,
        0,
        reg.KEY_ALL_ACCESS,
    )
    reg.DeleteKey(k, "CLSID")
    k.Close()

    k_2 = reg.CreateKey(
        reg.HKEY_CLASSES_ROOT,
        REG_PATH_CLSID_BAK,
    )
    reg.SetValue(k_2, "", reg.REG_SZ, E88DCCE0)
    reg.FlushKey(k_2)


def resume_clsid():
    """
    恢复Windows默认设置。
    原理是删除重新创建。
    """
    if not clsid_bak_is_e88dcce0():
        return

    k = reg.OpenKey(
        reg.HKEY_CLASSES_ROOT,
        REG_PATH_ZIP,
        0,
        reg.KEY_ALL_ACCESS,
    )
    reg.DeleteKey(k, "CLSID_BAK")
    k.Close()

    k_2 = reg.CreateKey(
        reg.HKEY_CLASSES_ROOT,
        REG_PATH_CLSID,
    )
    reg.SetValue(k_2, "", reg.REG_SZ, E88DCCE0)
    reg.FlushKey(k_2)


def show_title():
    """
    用户操作提示
    """
    print("")
    print("◆" + "■" * 27 + "◆")
    print('■启用/禁用"Windows将zip文件作为文件夹功能"		■')
    print("■							■")
    print("■👉禁用		请输入1				■")
    print("■👉启用		请输入2				■")
    print("■👉查询		请输入3				■")
    print("■👉退出		请输入4				■")
    print("■							■")
    print("■重要: 必须以管理员身份运行				■")
    print("■警告: 运行时会重启资源管理器				■")
    print("■							■")
    print("◆" + "■" * 27 + "◆")


def show_wrong_dialog(text="", title="错误"):
    """
    调用系统win32api弹窗
    """
    ctypes.windll.user32.MessageBoxTimeoutW(0, text, title, 16 | 0, 0, 3000)


def clear():
    """
    系统清屏命令
    """
    os.system(r"cls")


def restart_explorer():
    """
    重启资源管理器
    """
    os.system("taskkill /f /IM explorer.exe")
    os.system("start explorer.exe")


def is_admin():
    """
    判断是否以管理员身份运行
    """
    try:
        is_admin_bool = os.getuid() == 0
    except AttributeError:
        is_admin_bool = ctypes.windll.shell32.IsUserAnAdmin() != 0
    return is_admin_bool


if __name__ == "__main__":
    if is_admin():
        i = None
        clear()
        while True:
            if i not in [None, "1", "2", "3", "4"]:
                clear()
                show_title()
                show_wrong_dialog("不接受除1/2/3/4以外的输入", "错误的输入")
            else:
                show_title()

            print("")
            i = input("请输入：")
            if i == "1":
                backup_clsid()
                restart_explorer()
                input("按任意键返回")
                clear()
            elif i == "2":
                resume_clsid()
                restart_explorer()
                input("按任意键返回")
                clear()
            elif i == "3":
                info1 = clsid_is_e88dcce0()
                info2 = clsid_bak_is_e88dcce0()
                A = "" if info1 else "不"
                B = "" if info2 else "不"
                C = "启用" if info1 else "禁用"
                if info1 == info2:
                    print("CLSID和CLSID_BAK存在冲突, 这是不正常的")
                else:
                    print("查询结果:" + A + "存在CLSID, " + B + "存在CLSID_BAK, 当前为" + C + "状态")
                input("按任意键返回")
                clear()
            elif i == "4":
                import sys

                sys.exit()
    else:
        print("重要: 必须以管理员身份运行")
        show_wrong_dialog("必须以管理员身份运行", "错误的使用方法")
